'use strict'
const http = require("http");
const fs = require('fs');

/**
 *解析body数据的消息头
 *
 * @param {*} data
 */
function parseBodyHeaders(data) {
    let headers = {};
    let dsplit = data.split('\r\n').filter(p => p.length > 0) //filter()的作用是过滤序列
    let ind;
    let k;
    for (let d of dsplit) {
        ind = d.indexOf(':');
        if (ind <= 0) continue;
        k = d.substring(0, ind).toLowerCase();
        headers[k] = d.substring(ind + 1).trim(); //trim()方法用于去掉字符串首尾空格
    }

    let cpd = headers['content-disposition'];

    //按照;分割成数组，第一个元素form-data去掉
    let clist = cpd.split(';').splice(1);
    let name, filename;
    for (let a of clist) {
        ind = a.indexOf('filename="');
        if (ind >= 0) {
            filename = a.substring(ind + 10, a.length - 1);
            //ind+10：指filename="的长度
        } else {
            name = a.substring(6, a.length - 1);
        }
    }
    return {
        headers,
        name,
        filename,
    }
}

/**
 *
 *
 * @param {Buffer} bodyData 原始的body数据
 * @param {Object} reqHeader req.headers
 */

function parseBody(bodyData, reqHeaders) {
    //content-type:multipart/form-data;boundary=-----34294329
    let ctype = reqHeaders['content-type']; //标准格式

    // 拿到分界线boundary
    let bdy = ctype.substring(ctype.indexOf('=') + 1);

    // !数据用于分割文件的分界线
    //两次\r\n可以通过一次查找知道消息头和消息体
    // bdy = `--${bdy}\r\n`;

    let crlf_bdy = `\r\n--${bdy}`

    //从偏移crlf_bdy的长度开始查找下一个分界限的位置
    let data_end_index = bodyData.indexOf(crlf_bdy, crlf_bdy.length);
    //从下标crlf_bdy.length处开始查找，第一个crlf_bdy开始出现的地方

    //body消息数据中header部分的最后索引
    let header_end_index = bodyData.indexOf('\r\n\r\n', crlf_bdy.length);
    let header_data = bodyData.toString('utf-8', crlf_bdy.length, header_end_index);


    //解析body数据中的消息头
    let headers = parseBodyHeaders(header_data);

    let fileinfo = {
        start: header_end_index + 4, //由于连续的两个\r\n
        end: data_end_index,
    };
    fileinfo.length = fileinfo.end - fileinfo.start;
    return {
        name: headers.name,
        filename: headers.filename,
        headers: headers.headers,
        start: fileinfo.start,
        end: fileinfo.end,
        length: fileinfo.length,
    }
}
let routerTable = {
    GET: {
        '/upload': async (req, res) => {
            let stm = fs.createReadStream('./upload.html');
            stm.pipe(res);
            stm.on('end', () => {
                res.end();
            })
        }
    },
    POST: {
        '/upload': async (req, res) => {
            console.log(req.headers['content-type']);
            let bufferList = [];
            let totalLength = 0;
            req.on('data', (chunk) => {
                totalLength += chunk.length;
                bufferList.push(chunk)
            })
            let bodyData = null;
            req.on('end', () => {
                bodyData = Buffer.concat(bufferList, totalLength);
                bufferList = [];

                // 解析Body数据
                var body = parseBody(bodyData, req.headers);
                console.log(body);

                res.setHeader('Content-Type', 'text/plain;charset=utf-8');
                res.end(bodyData);
            })

        }
    }
};

let serv = http.createServer();
serv.on("request", (req, res) => {
    let rm = routerTable[req.method]

    // 根据？切分字符串
    let usplit = req.url.split("?");

    let pathname = usplit[0];
    let querystring = usplit[1] || ''; //如果没有问号的话，把空字符串传给querystring

    if (!rm || !rm[pathname]) {
        res.statusCode = 404;
        res.end('page not found');
        return;
    }
    rm[pathname](req, res);
})
serv.listen(3456);